package com.spring.framework.config.autowired.resource;

import com.spring.framework.config.autowired.model.AutowiredAllDemo;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Optional;

/**
 * @author xuweizhi
 * @since 2020/12/15 14:25
 */
@Component
@SuppressWarnings("all")
public class ResourceDemo {

	/**
	 * 注入已知可解析依赖项,@Resource的name优先级高于@Qualifier指定的值。
	 */
	@Resource
	private ApplicationContext context;

	//默认按照属性名->类型
	@Resource
	private AutowiredGeneric autowiredGenericA;

	@Resource
	private AutowiredGenericB autowiredGeneric;


	/**
	 * 指定bean name
	 */
	@Resource(name = "autowiredGenericA")
	private AutowiredGeneric autowiredGeneric1;

	/**
	 * 指定bean type
	 */
	@Resource(type = AutowiredGenericB.class)
	private AutowiredGeneric autowiredGeneric2;


	/**
	 * 指定bean name and class  要求都要匹配
	 */
	@Resource(name = "autowiredGenericB", type = AutowiredGeneric.class)
	private AutowiredGeneric autowiredGeneric3;


	private AutowiredGeneric autowiredGeneric4;
	private AutowiredGeneric autowiredGeneric5;
	private AutowiredGeneric autowiredGeneric6;
	private AutowiredGeneric autowiredGeneric7;
	private AutowiredGeneric autowiredGeneric8;

	/**
	 * 可以使用在方法上 同样是默认先name后type
	 */
	@Resource
	public void setter4(AutowiredGeneric autowiredGenericA) {
		this.autowiredGeneric4 = autowiredGenericA;
	}


	/**
	 * 可以配合Qualifier使用
	 */
	@Resource
	public void setter5(@Qualifier("autowiredGenericB") AutowiredGeneric autowiredGeneric) {
		this.autowiredGeneric5 = autowiredGeneric;
	}

	/**
	 * Resource和Qualifier都存在时，Resource的name 优先级更高
	 */
	@Resource(name = "autowiredGenericA")
	public void setter6(@Qualifier("autowiredGenericB") AutowiredGeneric autowiredGeneric) {
		this.autowiredGeneric6 = autowiredGeneric;
	}


//    /**
//     * 多参数方法将抛出异常
//     */
//    @Resource
//    public void setterTwo(AutowiredGeneric autowiredGenericA, AutowiredGeneric autowiredGenericB) {
//        this.autowiredGeneric7 = autowiredGenericA;
//        this.autowiredGeneric8 = autowiredGenericB;
//    }


	/**
	 * 支持Optional包装
	 */
	@Resource
	public void setterTwo(Optional<AutowiredAllDemo> autowiredAllDemo) {
		System.out.println(autowiredAllDemo);
	}

	@Component("autowiredGenericA")
	public static class AutowiredGenericA implements AutowiredGeneric {

	}

	@Component("autowiredGenericB")
	public static class AutowiredGenericB implements AutowiredGeneric {
	}

	public interface AutowiredGeneric {

	}

	@Override
	public String toString() {
		return "ResourceDemo{" + "\n" +
				"context=" + context + "\n" +
				"autowiredGenericA=" + autowiredGenericA + "\n" +
				", autowiredGeneric=" + autowiredGeneric + "\n" +
				", autowiredGeneric1=" + autowiredGeneric1 + "\n" +
				", autowiredGeneric2=" + autowiredGeneric2 + "\n" +
				", autowiredGeneric3=" + autowiredGeneric3 + "\n" +
				", autowiredGeneric4=" + autowiredGeneric4 + "\n" +
				", autowiredGeneric5=" + autowiredGeneric5 + "\n" +
				", autowiredGeneric6=" + autowiredGeneric6 + "\n" +
				", autowiredGeneric7=" + autowiredGeneric7 + "\n" +
				", autowiredGeneric8=" + autowiredGeneric8 +
				'}';
	}

	public static void main(String[] args) {
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ResourceDemo.class);
		System.out.println(applicationContext.getBean("resourceDemo", ResourceDemo.class));
	}
}
